
const Api = require('../net/api');
const http = require('../net/http');
const util = require('../utils/util');
const wxApi = require('../js/wxApi');
const STORE_USER_INFO_KEY = "USER_INFO";
const STORE_AUTH_FLAG_KEY = "AUTH_FLAG";

const userManager = {
  /**
   * 全局用户信息setter
   *
   * @param {Object} userInfo
   * @returns
   */
  setUserInfo( userInfo ) {
    let global = getApp().globalData;
    let logger = global.logger;
    
    if ( !userInfo ) {
      logger.info('the type of userInfo by setted is error!');
      return;
    }
    logger.info('set global & local userinfo succeed');
    global.__userInfo = userInfo;
    this.setLocalUserInfo( userInfo );
  },
  getUserInfo( callback ) {
    let global = getApp().globalData;
    let logger = global.logger;
    let self = this;
    let userInfo;

    callback = callback || function () {};
    // 全局对象获取用户信息
    userInfo = global.__userInfo; 
    if ( userInfo ) {
      logger.info('get userinfo from global succeed!');
      userInfo = util.deepClone( userInfo );
      this.onLoginSucceed( userInfo );
      callback (userInfo);
      return userInfo;
    }
    
    // 本地获取用户信息
    userInfo = this.getLocalUserInfo();
    if ( userInfo ) {
      logger.info('get userinfo from local succeed!')
      userInfo = util.deepClone( userInfo );
      this.onLoginSucceed( userInfo );
      global.__userInfo = userInfo;
      callback( userInfo )
      return userInfo;
    }
    // 如果本地没有用户信息重新请求登录
    // 如成功则以异步的方式传递用户信息
    this.userLogin( data => {
      wxApi.getLocation((loc) => {
        self.setLocation(loc)
      });
      data = util.deepClone( data );
      this.setUserInfo( data );
      callback( data );
    } )
  },
  setLocation(loc) {
    let global = getApp().globalData;
    global.loc = loc;
    global.http.addHeader({
      'latitude': loc.latitude,
      'longitude': loc.longitude
    })
    console.log(global);
  },
  clearUserInfo() {
    getApp() && (getApp().globalData.__userInfo = null);
    this.setLocalUserInfo(null);
  },
  userLogin( callback ) {
    let self = this;
    wx.showLoading({
      title: '',
      mask: true
    })
    this.login({
      success( data ) {
        self.onLoginSucceed( data );
        callback( data );
        wx.hideLoading();
        // getApp().globalData.setUserInfo( data );
      },
      noAuth() {
        wx.clearStorage();
        wx.redirectTo({
          url: '/pages/user/auth/auth'
        });
      },
      noBind() {
        wx.clearStorage();
        wx.redirectTo({
          url: '/pages/user/bind/bind'
        })
      }
    });
  },
  /**
   * 程序启动时登录验证
   *
   * @param {*} params
   */
  login( params ) {
    
    this.authLogin(( code, data ) => {
      
      switch ( code ) {
        // 授权登录成功（含本地已登录状态）
        case 0: {
          console.log(data);
          params.success && params.success(data);
        } break;
        // 未授权
        case 1: {
          params.noAuth && params.noAuth(null); 
        } break;
        // 已授权新用户
        case 2: {
          params.noBind && params.noBind(null);
        } break
      }
    })
  },
  onLoginSucceed( userInfo ) {
    let global = getApp().globalData;
    // 隐藏loading
    wx.hideLoading();
    global.http.addHeader({
      'access-token': userInfo.token
    })
  },
  /**
   * 主登录逻辑 回调函数返回枚举类型
   * 参数 code
   * 0: 登录成功
   * 1: 未授权，通知用户授权
   * 2: 新用户授权成功，通知用户绑定 
   * 
   * 参数 data
   * data: null (code为 1)
   * data: UserData (code为 0, 注册的用户信息)
   * data: UserInfo (code为 2, 从微信获取的用户信息)
   * @param {Function} fn
   */
  authLogin( fn ) {
    let 
      self = this,
      userdata;
      
    fn = fn || function () {};
    console.log('检测登录授权');
    this.detectAuth({
      // 未授权登录
      noAuth() {
        logger('user has no auth yet');
        fn( 1, null )
      },
      // 已授权
      authed() {
        
        self.getAuthInfo( authInfo => {
          if ( authInfo ) {
            console.log( '授权成功' );
            console.log(authInfo);
            Api.authLogin( authInfo, (data, code) => {
              console.log('登录')
              console.log( data );
              // 登录请求成功
              if ( code === 0) {
                logger('request auth login succeed.')
                fn ( 0, data );
                return;
              }
              // 用户未绑定，登录失败
              if ( code === 10 ) {
                logger('request auth succeed, but has no bind.')
                fn ( 2, authInfo );
                return;
              }
            })
          }
        })
      }
    })
  },
  /**
   * 检验用户是否授权
   *
   * @param {Object} params noAuth, authed
   */
  detectAuth( params ) {
    wx.getSetting({
      success( res ) {
        if ( !res.authSetting['scope.userInfo'] ) {
          logger('user has no auth!')
          params.noAuth && params.noAuth();
        } else {
          params.authed && params.authed()
        }
      },
      fail(res) {
        console.log(res)
      }
    })
  },
  /**
   * 认证后获取微信用信息
   *
   * @param {Function} fn
   * @returns data
   */
  getAuthInfo( fn ) {
    
    let 
      authCode,
      encryptedData,
      iv,
      params,
      self = this;
  
    wx.login({
      success( loginRes ) {
        authCode = loginRes.code;
        if ( !authCode ) {
          logger('get wxUserInfo error: ' + JSON.stringify(loginRes));
          fn( null )
          return;
        };
        wx.getUserInfo({
          success( userRes ) {
            encryptedData = userRes.encryptedData;
            iv = userRes.iv;
            if ( !encryptedData || !iv ) {
              logger('get wx userinfo error：' + JSON.stringify(userRes));
              fn( null )
              return;
            }
            logger('get wx userinfo success');
            params = {
              authCode,
              encryptedData,
              iv
            }
            fn( params );
          }
        })
      }
    })
  },
  /**
   * 本地存储用户信息
   *
   * @param {Object} userInfo
   */
  setLocalUserInfo( userInfo ) {
    wx.setStorage({
      key: STORE_USER_INFO_KEY,
      data: userInfo,
      success() {
        logger('userinfo are saved succeed.');
      }
    })
  },
  /**
   * 获取本地用户信息
   *
   * @param {Object} fn
   */
  getLocalUserInfo() {
    return this.getLocalSync( STORE_USER_INFO_KEY );
  },
  /**
   * 设置用户拒绝授权
   * flag 1: 拒绝
   * @param {Number} flag
   */
  setRefuseAuth( flag ) {
    this.setLocalAsync(STORE_AUTH_FLAG_KEY, flag);
  },
  /**
   * 获取用户拒绝授权状态
   *
   * @returns
   */
  getRefuseAuth() {
    return this.getLocalSync( STORE_AUTH_FLAG_KEY );
  },
  /**
   * 本地数据异步缓存
   *
   * @param {String} key
   * @param {Any} data
   */
  setLocalAsync(key, data) {
    wx.setStorage({
      key: key, //
      data: data,
      success() {
        logger('set ' + key + ' to local succeed.')
      }
    })
  },
  /**
   * 同步获取本地数据
   *
   * @param {String} key
   * @returns
   */
  getLocalSync( key ) {
    try {
      var data = wx.getStorageSync( key )
      if (data || data === false || data === 0) {
        logger('get ' + key + ' from local succeed.')
        return data;
      }
      return null;
    } catch (e) {
      // Do something when catch error
    }
  }
}
function logger(text) {
  console.log('user manager: ' + text);
}
module.exports = userManager;